package com.lipaluma.excel.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;

import com.lipaluma.excel.config.ExcelConfiguration;
import com.lipaluma.excel.config.ExcelExtension;
import com.lipaluma.exceptions.CsvParserException;
import com.lipaluma.io.SourceFactory;
import com.lipaluma.io.SourceReader;
import com.lipaluma.io.SourceWriter;
/**
 * ConfigurationFile for Excel entry file
 * @author Mario
 */
public class ExcelSourceFactory implements SourceFactory {
	public static final String XLS_TYPE = "Excel";
	public static final String XLSX_TYPE = "XLSX";
	
	private String sheetName;
	private Integer sheetIndex;
	private final ExcelExtension extension;
	
	public ExcelSourceFactory(ExcelConfiguration configuration) {
		this.extension = configuration.getExtension();
		this.sheetIndex = configuration.getSheetIndex();
		this.sheetName = configuration.getSheetName();
	}

	/**
	 * create a Excel Configuration File for the specified excel type (Excel, XSLX).
	 * <p>
	 * the sheet index equals to 0
	 * @param fileType the file type (Excel or XLSX)
	 */
	public ExcelSourceFactory(ExcelExtension extension) {
		this.extension = extension;
		this.sheetIndex = 0;
	}
	/**
	 * create a Excel Configuration File for the specified excel type (Excel, XSLX) and the specified sheet index
	 * @param fileType the file type (Excel or XLSX)
	 * @param sheetIndex the sheet index
	 */
	public ExcelSourceFactory(ExcelExtension extension, int sheetIndex) {
		this.extension = extension;
		this.sheetIndex = sheetIndex;
	}
	/**
	 * create a Excel Configuration File for the specified excel type (Excel, XSLX) and the specified sheet name
	 * @param fileType the file type (Excel or XLSX)
	 * @param sheetName the sheet name
	 */
	public ExcelSourceFactory(ExcelExtension extension, String sheetName) {
		this.extension = extension;
		this.sheetName = sheetName;
	}
	
	/**
	 * get index of the sheet
	 * @return index
	 */
	public Integer getSheetIndex() {
		return sheetIndex;
	}
	
	/** 
	 * return the name of the sheet
	 * @return sheet name
	 */
	public String getSheetName() {
		return sheetName;
	}
	
	public SourceReader createSourceReader(Reader reader) {
		Workbook workbook = null;
		try {
			workbook = extension.createWorkbook(reader);
		} catch (IOException e) {
			throw new CsvParserException("can't open the excel file", e);
		}
		
		if(StringUtils.isNotBlank(sheetName))
			return new ExcelReader(workbook, sheetName);
		else if(sheetIndex != null)
			return new ExcelReader(workbook, sheetIndex);
		else
			return new ExcelReader(workbook);
	}
	public SourceReader createSourceReader(InputStream in) {
		Workbook workbook = null;
		try {
			workbook = extension.createWorkbook(in);
		} catch (IOException e) {
			throw new CsvParserException("can't open the excel file", e);
		}
		
		if(StringUtils.isNotBlank(sheetName))
			return new ExcelReader(workbook, sheetName);
		else if(sheetIndex != null)
			return new ExcelReader(workbook, sheetIndex);
		else
			return new ExcelReader(workbook);
	}
	
	public SourceWriter createSourceWriter(Writer writer) {
		throw new CsvParserException("The Excel files can't be written by a writer. Please, use OutputStream instead.");
	}
	
	public SourceWriter createSourceWriter(OutputStream out) {
		Workbook workbook = extension.createWorkbook();		
		
		if(StringUtils.isNotBlank(sheetName))
			return new ExcelWriter(out, workbook, sheetName);
		else
			return new ExcelWriter(out, workbook);
	}
}
